/*!
 * @author Austin Andrews (Templarian)
 * @authorurl http://templarian.com
 * @framework DD Framework
 * @licence New BSD License
 * @licenceurl http://ddframework.googlecode.com/svn/trunk/license.txt
 * @overview Core
 */
/**
 * Namespace
 * @property {Array} window.ns Current namespace.
 */
window.ns = [];
/**
 * Extend
 */
window.extend = function()
{
    var a = arguments;
    if(a.length == 1 && typeof(a[0]) == "object")
    {
        this.extend(null, a[0]);
    }
    else if(a.length == 1)
    {
        this.extend(a[0], function(){});
    }
    else if(a.length == 2 && typeof(a[1]) == "function")
    {
        var head = document.getElementsByTagName("head")[0];
        if(typeof rootPath == "undefined")
        {
            for(var i = 0; i < head.childNodes.length; i++)
            {
                var t, m = head.childNodes[i].nodeName.match(/script/i)
                    ? (t = head.childNodes[i].getAttribute("src").match(/^(.*?)(!?\/dd)\/dd\.js$/))
                        ? t[1].split("/")
                        : null
                    : null;
                if(m)
                {
                    window.rootPath = m;
                    break;
                }
            }
        }
        var m = a[0].match(/^(~?)(\/?)(.*?)(\.js|)$/),
        cS = function(c)
        {
            var a = [];
            for(var i = 0; i < c; i++)
            {
                a.push("..");
            }
            return a;
        },
        iR = m[1] == "",                                 // is Relative
        iA = m[2] != "",                                 // is Absolute
        iJ = m[4] != "",                                 // is JavaScript
        sJ = "." + m[4],                                 // ?
        rC = (m[3].match(/\.\.\//g) || []).length,       // Count ../ folders
        aP = (iR ? rootPath : []),                       // ?
        tP = m[3].split("/"),                            // split "file/module"
        sP = tP[tP.length - 1].split("."),               // ["dd", "xml"]
        tS = sP.splice(0, sP.length - 1),                // ?
        fP = tP.slice(0, tP.length - rC - 1),            // folder path
        rP = fP.concat(sP), // ?
        rTP = rP.slice(0),                               // ?
        rPL = rTP.pop(),                                 // module name
        ns = this.ns.concat(tS),                         // namespace
        nsC = ns.length,                                 // namespace count
        file = nsC == 0                                  // setup file path
            ? aP.concat([rPL, rPL]).join("/") + ".js"
            : nsC == 1
                ? (iR ? aP : (iA ? [""].concat(rTP) : cS(rC)).concat(["scripts"]))
                    .concat([ns[0], ns[0]]).join("/") + "." + rPL + ".js"
                : nsC == 2 && ns[1] == "project"
                    ? aP.concat(fP, [rPL, rPL]).join("/") + ".js"
                    : nsC > 2 && ns[1] == "project"
                        ? aP.concat(fP, [ns[2], ns[2]]).join("/") + "." + rPL + ".js"
                        : "fail";
        // fix this to point at the right location
        var exists = window.extend(ns.concat(sP).join("."), {});
        dd.log("(" + ns.join(".") + ", " + rP.join(".") + ")->(" + file + ") Exists = " + exists);
        if(!exists)
        {
            var s = document.createElement("script")
            s.type = "text/javascript";
            s.src = file;
            head.appendChild(s);
        }
    }
    else if(a.length == 2 && typeof a[0] == "object" && a[0] != null)
    {
        for(var i in a[1])
        {
            a[0][i] = a[1][i];
        }
    }
    else
    {
        var r = false,
            p = this,
            n = a[0] == null ? [] : a[0].split("."),
            x = this.ns.concat(x);
        for(var nC = n.length, i = 0; i < nC; i++)
        {
            if(typeof(p[n[i]]) == "undefined")
            {
                p[n[i]] = (function(p, i)
                    {
                        return function()
                        {
                            if(typeof(p[i].func) == "undefined")
                            {
                                p[i].extend.apply(p[i], arguments);
                                //dd.log("remove: " + i + "; dd.body = " + typeof dd.body);
                                //dd.moduleList.shift(dd.moduleList.indexOf(this.ns.join(".")), 1);
                                //if(dd.moduleList.length == 0)
                                //{
                                    //dd.log("Call ready methods...");
                                //    delete dd.moduleList;
                                //}
                            }
                            else
                            {
                                return p[i].func.apply(p[i], arguments);
                            }
                            return true;
                        };
                    })(p, n[i]);
                p[n[i]].ns = n.slice(0, i + 1);
                p[n[i]].extend = extend;
                p[n[i]].parent = p;
            }
            else if(i == nC - 1)
            {
                r = true;
            }
            p = p[n[i]];
        }
        var s = typeof p.override == "object",
            iE = function(o) { for(var i in o){ return false; } return true; };
        for(var i in a[1])
        {
            if(!iE(a[1][i]) && typeof a[1][i] == "object"
               && !(a[1][i] instanceof Array)
               && typeof a[1][i].self == "undefined"
               && i != "override")
            {
                if(i == "fn")
                {
                    for(var j in a[1][i])
                    {
                        p.fn.prototype[j] = a[1][i][j];
                    }
                }
                else
                {
                    p.extend(i, a[1][i]);
                }
            }
            else
            {
                // handle get and set also!
                if(typeof a[2] == "boolean" ? a[2] : true)
                {
                    p[i] = a[1][i];
                }
                if(s && i in p.override)
                {
                    p.override[i].call(p);
                }
            }
        }
        if(typeof p.init == "function")
        {
            processInit({ o: p, i: 0 });
        }
        return r;
    }
    return {};
};
/**
 * Temporary processing queue until dom is ready
 */
window.processList = [];
/**
 * Temporary processing call until dom is ready
 */
window.processInit = function(p)
{
    processList.push(p);
    processList.sort(function(a, b){
        return a.i - b.i
    });
};
/**
 *
 */
/**
 * Process all waiting initialization methods
 */
window.onload = function()
{
    for(var i = 0; i < processList.length; i++)
    {
        processList[i].o.init.call(processList[i]);
    }
    delete window.processList;
    processInit = function(p)
    {
        p.o.init.call(p);
    };
};
// DD Framework
window.extend("dd", {
    init: function()
    {
        // Easy reference
        dd.body = {
            self: {
                e: document.getElementsByTagName("body")[0]
            }
        };
        // Always null out drag on mouseup
        dd.event({
            mouseup: function()
            {
                if(dd.event.drag != null)
                {
                    document.removeEventListener("mousemove", dd.event.drag.listener, true);
                    dd.event.drag = null;
                }
            }
        });
        // Call init
        
    },
    func: function(o1, o2)
    {
        return typeof o2 == "undefined"
            ? typeof o1 == "string"
                ? dd.selector(o1) // Selector String
                : typeof o1 == "undefined"
                    ? dd.log("Invalid dd parameter", dd.log.error)
                    : typeof o1 == "function"
                        ? processInit({ o: {init:o1}, i: 1 })
                        : "self" in o1
                            ? "fn" in o1.self
                                ? new o1.self.fn(o1) // Custom Control
                                : new dd.fn(o1) // Element
                            : dd.setup.call(dd, o1) // Config / Empty
            : function()
            {
                dd.combine(this, o2);
                o1.apply(this, arguments);
            };
    },
    hasProperty: function(o, p)
    {
        return Object.prototype.hasOwnProperty.call(o, p)
    },
    /**
     * Trim whitespace
     * @namespace dd.trim
     * @function
     *  @param str {string} String to trim
     */
    trim:function(v)
    {
        return v.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
    },
    project: { ns: ["dd", "project"] },
    moduleList: [],
    setup: function(o)
    {
        if(typeof o.debug == "boolean" && o.debug)
        {
            dd.extend("debug");
        }
        for(var m = 0; m < (o.modules || []).length; m++)
        {
            dd.extend(o.modules[m]);
            this.moduleList.push(o.modules[m]);
        }
        for(var p in (o.projects || []))
        {
            dd.project.extend(p);
            var b = p.match(/(.*?)([\w\.]+)$/);
            for(var f = 0; f < o.projects[p].length; f++)
            {
                var n = o.projects[p][f];
                dd.project[b[2]].extend(n.match(/~|\//) ? n: b[1] + n);
            }
        }
    },
    captureMoves: function(e)
    {
        e.stopPropagation();
    },
    captureStops: function(e)
    {
        e.stopPropagation();
    },
    addListener: function(element, type, callback, capture) {
        if (element.addEventListener) {
            element.addEventListener(type, callback, capture);
        } else {
            element.attachEvent("on" + type, callback);
        }
    },
    /**
     * toPx
     * If intenger return i + px
     */
    toPx: function(i)
    {
        return i + (isNaN(i) ? "" : "px");
    },
    /**
     * toInt
     * If string return int or 0
     */
    toInt: function(s)
    {
        return parseInt((s || "0").replace("px", ""));
    },
    /**
     * Global Events.
     */
    event: {
        func: function(o, s)
        {
            return dd({
                self: {
                    e: document
                }
            }).event(o, s || {});
        },
        drag: null,
        cancelClick: false,
        delta: { x: 0, y: 0 },
        down: {
            left: false,
            right: false
        }
    },
    /**
     * Dom events
     */
    events: {
        load: function(e){
            return {
                capture:false
            };
        },
        resize: function(e)
        {
            return {
                capture:false,
                screen:{
                    width: window.innerWidth,
                    height: window.innerHeight
                }
            };
        },
        scroll: function(e)
        {
            return {
                capture: false,
                scroll: {
                    height: e.target.scrollHeight,
                    top: e.target.scrollTop
                },
                screen: {
                    scrollY: window.pageYOffset,
                    width: window.innerWidth,
                    height: window.innerHeight
                }
            };
        },
        mouseover: function(e)
        {
            return {
                capture:false,
                mouse: {
                    left: "which" in e
                        ? e.which == 1
                        : e.button == 0
                }
            };
        },
        mouseout: function(e)
        {
            return {
                capture: false,
                mouse: {
                    x: e.clientX,
                    y: e.clientY
                }
            };
        },
        mousemove: function(e)
        {
            var p = dd.mousePosition(e);
            var d = {
                x: p.x - dd.event.delta.x,
                y: p.y - dd.event.delta.y
            };
            dd.event.delta = dd.mousePosition(e);
            return {
                capture: false,
                mouse: {
                    x: e.pageX || e.layerX,
                    y: e.pageY || e.layerY,
                    delta: d,
                    left: dd.event.down.left = (e.which)
                        ? (e.which == 1)
                        : (e.button == 1),
                    right: dd.event.down.right = (e.which)
                        ? (e.which == 3)
                        : (e.button == 2),
                }
            };
        },
        mousedown: function(e)
        {
            dd.event.delta = dd.mousePosition(e);
            return {
                capture: false,
                captureMouse: function()
                {
                    this.captures = true;
                },
                target: { self: { e: e.target } },
                currentTarget: { self: { e: e.currentTarget } },
                mouse:{
                    left: dd.event.down.left = (e.which)
                        ? (e.which == 1)
                        : (e.button == 1),
                    right: dd.event.down.right = (e.which)
                        ? (e.which == 3)
                        : (e.button == 2),
                    x: e.pageX || e.layerX,
                    y: e.pageY || e.layerY
                }
            };
        },
        mouseup: function(e)
        {
            dd.event.down = { left: false, right: false };
            return {
                capture:false,
                releaseMouse:function()
                {
                    releases = true;
                },
                target:{self:{e:e.target}},
                currentTarget:{self:{e:e.currentTarget}},
                mouse:{
                    left:(e.which) ? (e.which == 1) : (e.button == 1),
                    right:(e.which) ? (e.which == 3) : (e.button == 2),
                    x:e.pageX || e.layerX,
                    y:e.pageY || e.layerY
                }
            };
        },
        contextmenu: function(e)
        {
            return {
                capture:true,
                mouse:{
                    x:e.pageX || e.clientX + document.body.scrollLeft,
                    y:e.pageY || e.clientY + document.body.scrollTop
                }
            };
        },
        keypress: function(e)
        {
            var c = 0;
            if (e.keyCode) c = e.keyCode;
            else if (e.which) c = e.which;
            return {
                capture:false,
                scroll:{
                    height:e.target.scrollHeight
                },
                key:{
                    code:c,
                    character:String.fromCharCode(c),
                    tab:c == 9,
                    enter:c == 13,
                    ctrl:e.ctrlKey,
                    shift:e.shiftKey
                }
            };
        },
        keydown: function(e)
        {
            var c = 0;
            if (e.keyCode) c = e.keyCode;
            else if (e.which) c = e.which;
            return {
                capture:false,
                key:{
                    code:c,
                    character:String.fromCharCode(c),
                    tab:c == 9,
                    enter:c == 13,
                    ctrl:e.ctrlKey,
                    shift:e.shiftKey
                }
            };
        },
        keyup: function(e)
        {
            var c = 0;
            if (e.keyCode) c = e.keyCode;
            else if (e.which) c = e.which;
            return {
                capture:false,
                key:{
                    code:c,
                    character:String.fromCharCode(c),
                    tab:c == 9,
                    enter:c == 13,
                    ctrl:e.ctrlKey,
                    shift:e.shiftKey
                }
            };
        },
        focus: function(e)
        {
            return {capture:false};
        },
        blur: function(e)
        {
            return {capture:false};
        },
        change: function(e)
        {
            return {
                capture:true
            };
        },
        click: function(e)
        {
            return {
                capture:true,
                target:{self:{e:e.target}},
                currentTarget:{self:{e:e.currentTarget}}
            };
        },
        dblclick: function(e)
        {
            return {
                capture:true,
                target:{self:{e:e.target}},
                currentTarget:{self:{e:e.currentTarget}}
            };
        }
    },
    mousePosition: (function()
    {
        if(typeof window.pageXOffset !== "undefined"){
            return function(ev)
            {
                return {
                    x: ev.clientX + window.pageXOffset,
                    y: ev.clientY + window.pageYOffset
                };
            }
        }
        else
        {
            return function()
            {
                var ev = window.event,
                    d = document.documentElement,
                    b = document.body;
                return {
                    x: ev.clientX+d.scrollLeft + b.scrollLeft,
                    y: ev.clientY+d.scrollTop + b.scrollTop
                };
            }
        }
    })(),
    fn: function(o)
    {
        this.self = o.self;
        this.addElement = function(o1, o2, o3, o4)
        {
            var e = {};
            if(typeof o1 == "string")
            {
                e = document.createElement(o1);
            }
            else if(typeof o1 == "object")
            {
                for(var i in o1)
                {
                    e = document.createElementNS(hns[i], i + ":" + o1[i]);
                }
            }
            var setAttribute = function(e, o)
            {
                for(var j in o)
                {
                    if(j == "class" || j == "className")
                    {
                        e.className = o[j];
                    }
                    else if(j == "style" && typeof o[j] == "object")
                    {
                        this.css.call({self:{e:e}}, o[j]);
                    }
                    else
                    {
                        e.setAttribute(j, o[j]);
                    }
                }
            };
            if(typeof o2 == "object")
            {
                setAttribute.call(this, e, o2);
            }
            else if(typeof o2 == "string" || typeof o2 == "number")
            {
                if(o2 != "")
                {
                    e.appendChild(document.createTextNode(o2));
                }
            }
            if(o3)
            {
                setAttribute.call(this, e, o3);
            }
            if(typeof o1 == "boolean" || typeof o2 == "boolean"
               || typeof o3 == "boolean" || typeof o4 == "boolean")
            {
                this.self.e.insertBefore(e, this.self.e.firstChild);
            }
            else
            {
                this.self.e.appendChild(e);
            }
            return {
                self: {
                    e: e,
                    event: {}
                }
            };
        };
        this.empty = function()
        {
            var e = this.self.e;
            while(e.childNodes[0])
            {
                e.removeChild(e.childNodes[0]);
            }
        };
        this.css = function()
        {
            var a = arguments;
            if(typeof a[0] == "string")
            {
                if(a.length == 1)
                {
                    return this.self.e.style[a[0]];
                }
                else
                {
                    return this.self.e.style[a[0]] = a[1];
                }
            }
            else
            {
                for(var i in a[0])
                {
                    this.self.e.style[i] = a[0][i];
                }
            }
            return this;
        };
        this.cssValue = function(n)
        {
            return dd.toInt(this.css.call(this, n));
        },
        /**
         * nodeName
         */
        this.nodeName = function()
        {
            return this.self.e.nodeName;
        };
        /**
         * toggle
         */
        this.toggle = function()
        {
            return (this.css("display") == "none"
                ? this.show().css("display")
                : this.hide().css("display")) != "none";
        };
        /**
         * Show
         */
        this.show = function()
        {
            this.css("display", "block");
            return this;
        };
        /**
         * Hide
         */
        this.hide = function()
        {
            this.css("display", "none");
            return this;
        };
        /**
         * Value
         */
        this.value = function(v)
        {
            var e = this.self.e,
                s = typeof v == "undefined";
            return e.nodeValue == "checkbox"
                ? s ? e.checked = v : e.checked
                : s ? e.value = v : e.value;
        };
        /**
         * Text
         */
        this.text = function(v)
        {
            var e = this.self.e;
            if(typeof v == "undefined")
            {
                return e.childNodes.length > 0
                        ? e.childNodes[0].nodeValue
                        : "";
            }
            else
            {
                while(e.childNodes[0])
                {
                    e.removeChild(e.childNodes[0]);
                }
                var p = v.toString().split(/\r?\n/);
                if(p.length == 1)
                {
                    e.appendChild(document.createTextNode(p[0]));
                }
                else
                {
                    for(var i in p)
                    {
                        e.appendChild(document.createTextNode(p[i].replace(/ /g, "\u00a0")));
                        if(i != p.length - 1)
                        {
                            e.appendChild(document.createElement("br"));
                        }
                    }
                }
                return v;
            }
        };
        /**
         * ClassName
         */
        this.className = function(v)
        {
            var e = this.self.e;
            return typeof v == "string"
                ? typeof e.className == "object"
                    ? e.className.baseVal = v
                    : e.className = v
                : typeof e.className == "object"
                    ? e.className.baseVal
                    : e.className;
        };
        /**
         * Add's a CSS class to an element 
         * @namespace dd.fn.addClass
         * @function
         *  Add element to DOM
         *  @param name {string} Class name
         *  @returns element
         */
        this.addClass = function(name)
        {
            var c = dd(this).className().split(/ /);
            c.push(name);
            dd(this).className(dd.trim(c.join(" ")));
            return this;
        };
        /**
         * Removes a CSS class from an element 
         * @namespace dd.fn.removeClass
         * @function
         *  Remove class from element
         *  @param name {string} Class name
         *  @returns element
         * @function
         *  Add element to DOM
         *  @param name {array} Class names
         *  @returns element
         */
        this.removeClass = function(o)
        {
            if(typeof o == "string")
            {
                dd(this).className(dd.trim((dd(this).className() + " ").replace(new RegExp(" ?" + o + " ?", "g"), " ")));
            }
            else
            {
                for(var i = 0; i < o.length; i++)
                {
                    dd(this).removeClass(o[i]);
                }
            }
            return this;
        };
        /**
         * Clears CSS classes on element 
         * @namespace dd.fn.clearClass
         * @function
         *  Clears out the class on element
         *  @returns element
         */
        this.clearClass = function()
        {
            dd(this).className("");
            return this;
        };
        /**
         * Checks if class exists
         * @namespace dd.fn.classExists
         * @function
         *  Check class exists
         *  @param name {string} Class name
         *  @returns boolean
         * @function
         *  Check if at least one of the classes exists
         *  @param name {array} Class names
         *  @returns boolean
         */
        this.hasClass = function(o)
        {
            if(typeof o == "string")
            {
                return !!~(" " + dd(this).className() + " ").indexOf(" " + o + " ");
            }
            else
            {
                for(var i = 0; i < o.length; i++)
                {
                    if(dd(this).hasClass(o[i]))
                    {
                        return true;
                    }
                }
                return false;
            }
        };
        /**
         * transform css
         */
        this.transform = function()
        {
            var a = arguments;
            if(a.length == 2) // "left", 20
            {
                var m = this.css.call(this, a[0]).match(/(-?\d+)(\w+|%)/);
                var i = parseInt(m[1]);
                return this.css.call(this, a[0], (i + a[1]) + m[2]);
            }
            for(var i in a[0])
            {
                a[i] = this.transform(i, a[0][i]);
            }
            return a[0];
        };
        /**
         * Set an element's attribute 
         * @namespace dd.fn.setAttribute
         * @function
         *  Add element to DOM
         *  @param name {string} Attribute name
         *  @param value {string} Attribute value
         */
        this.setAttribute = function(o1, o2)
        {
            if(typeof o1 == "string")
            {
                this.self.e.setAttribute(o1, o2);
            }
            else
            {
                for(var i in o1)
                {
                    this.self.e.setAttribute(i, o1[i]);
                }
            }
            return this;
        };
        /**
         * Get an element's attribute 
         * @namespace dd.fn.getAttribute
         * @function
         *  Add element to DOM
         *  @param name {string} Element name
         */
        this.getAttribute = function(name)
        {
            return this.self.e.getAttribute(name);
        };
        /**
         * Removes an attribute 
         * @namespace dd.fn.removeAttribute
         * @function
         *  Add element to DOM
         *  @param name {string} Attribute name
         */
        this.removeAttribute = function(name)
        {
            this.self.e.removeAttribute(name);
        };
        this.scrollTop = function(v)
        {
            if(typeof v == "undefined")
            {
                return this.self.e.scrollTop;
            }
            else
            {
                return this.self.e.scrollTop = v;
            }
        };
        this.scrollHeight = function(v)
        {
            if(typeof v == "undefined")
            {
                return this.self.e.scrollHeight;
            }
            else
            {
                return this.self.e.scrollHeight = v;
            }
        };
        /**
         * Triggers an event
         * @namespace dd.fn.trigger
         * @function
         *  Triggers an event
         *  @param event {string} Event name
         * @function
         *  Triggers an event with variables
         *  @param event {string} Event name
         *  @param variables {object} Variable scope to pass
         */
        this.trigger = function(n, s)
        {
            if("event" in this.self)
            {
                var t = this.self.event;
                var f = { self: this.self };
                for(var i in t[n])
                {
                    t[n][i].call(f);
                }
            }
            return this;
        },
        /**
         * Apply events to objects
         * @namespace dd.fn.event
         * @function
         *  @param events {object} Events
         * @function
         *  @param events {object} Events
         *  @param scope {object} Pass into scope
         */
        this.event = function(o, s)
        {
            // Element container
            var p = {
                self: this.self
            };
            // Event object
            if(!("event" in p.self))
            {
                p.self.event = {};
            }
            // Scope data
            for(var j in s)
            {
                p[j] = s[j];
            }
            for(var i in o)
            {
                if(!(i in p.self.event))
                {
                    p.self.event[i] = [];
                }
                p.self.event[i].push(o[i]);
                if(this.self.e !== null)
                {
                    if(i == "dblclick" && !("mousedown" in o))
                    {
                        this.event({
                            mousedown: function() { return false; }
                        });
                    }
                    else if(i == "drag") // TODO Integrate this a lot nicer!!!
                    {
                        var element = p.self.e;
                        dd.addListener(element, "mousedown", function(e) {
                            e = window.event || e;
                            dd.event.drag = dd.events.mousemove(e);
                            dd.event.drag.start = {
                                x: parseInt(element.style.left),
                                y: parseInt(element.style.top)
                            };
                            if (element.setCapture) element.setCapture();
                            var dragTarget = element.setCapture ? element : document;
                            dd.event.drag.listener = (function(iP, iI, iF){
                                return function(e) {
                                    var d = dd.event.drag;
                                    if (!d) return;
                                    e = window.event || e;
                                    dd.event.cancelClick = true;
                                    var t = dd.events.mousemove(e);
                                    for(var z in t)
                                    {
                                        iP[z] = t[z];
                                    }
                                    iP.x = d.start.x + (e.clientX - d.mouse.x);
                                    iP.y = d.start.y + (e.clientY - d.mouse.y);
                                    iF.call(iP);
                                };
                            })(p, i, o[i]);
                            dd.addListener(dragTarget, "mousemove", dd.event.drag.listener, true);
                        });
                        dd.addListener(element, "losecapture", function() {
                            dd.event.drag = null;
                        });
                        continue;
                    }
                    this.self.e.addEventListener(i, (function(se, k, f)
                    {
                        return function(e)
                        {
                            var v = dd.events[k].call(this, e), // attach to object
                                ele = se.self.e;
                            if(v)
                            {
                                for(var i in se)
                                {
                                    v[i] = se[i];
                                }
                                var r = (k == "click" || k == "dblclick") && dd.event.cancelClick
                                    ? false : f.call(v);
                                r = typeof r == "boolean" ? !r : v.capture;
                                if(r)
                                {
                                    e.cancelBubble = true;
                                    if(e.stopPropagation)
                                    {
                                        e.stopPropagation();
                                    }
                                    if(e.preventDefault)
                                    {
                                        e.preventDefault();
                                    }
                                    else
                                    {
                                        e.returnValue = false;
                                    }
                                }
                                if(k == "click" || k == "dblclick")
                                {
                                    dd.event.cancelClick = false
                                }
                            }
                        }
                    })(p, i, o[i]), true);
                }
            }
            return this;
        };
        /**
         * Parent
         */
        this.parent = function()
        {
            return new dd.fn({
                self: {
                    e: this.self.e.parentNode
                }
            });
        },
        /**
         * Parent
         */
        this.each = function(f)
        {
            for(var i = 0; i < this.self.e.childNodes.length; i++)
            {
                f.call({self:{e:this.self.e.childNodes[i]}});
            }
        },
        /**
         * Set focus to an element
         * @function
         *  Sets focus
         */
        this.focus = function()
        {
            this.self.e.focus();
        };
        /**
         * Set focus to an element
         * @function
         *  Sets focus
         */
        this.select = function()
        {
            this.self.e.select();
        };
    },
    log: {
        func: function(message, level)
        {
            level = level || this.debug;
            this.logList.push({
                message: message,
                level: level
            });
        },
        override: {
            func: function()
            {
                for(var i = 0; i < this.logList.length; i++)
                {
                    this(this.logList[i].message, this.logList[i].level);
                }
                delete this.logList;
            }
        },
        debug: "debug",
        error: "error",
        logList: []
    },
    json:function(o)
    {
        if(typeof o == "string")
        {
            return JSON.parse(o);
        }
        else
        {
            return JSON.stringify(o);
        }
    },
    head: {
        self: {
            e: document.getElementsByTagName("head")[0]
        }
    },
    hns: {
        "svg": "http://www.w3.org/2000/svg"
    }
});